<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3.分形图案</title>
    <style>
        canvas{
            border:1px solid #aaa;
            margin: 0 auto;
            display: block;
        }
    </style>
</head>
<body>
    <canvas width="600" height="600"></canvas>

    <script src="/common/lib/gl-renderer.js"></script>

    <script type="module">
        /**
         * gl-renderer 在 WebGL 底层的基础上进行了一些简单的封装，以便于我们将重点放在提供几何数据、设置变量和编写 Shader 上，不用因为创建 buffer 等细节而分心
         * 第一步: 创建 Renderer 对象
         * 第二步: 创建并启用 WebGL 程序
         * 第三步: 设置 uniform 变量
         * 第四步: 将顶点数据送入缓冲区
         * 第五步: 渲染
        */

        //第一步:
        const canvas = document.querySelector('canvas');
        const renderer = new GlRenderer(canvas);

        const vertex = `
            attribute vec2 a_vertexPosition;
            attribute vec2 uv;
            varying vec2 vUv;

            void main(){
                gl_PointSize = 1.0;
                vUv = uv;
                gl_Position = vec4(a_vertexPosition,1.0,1.0);

            }
        
        `
        // // 渲染方格
        // const fragment = `
        //     #ifdef GL_ES
        //     precision highp float;
        //     #endif

        //     uniform float utime;
        //     uniform int rows;
        //     varying vec2 vUv;
            
        //     vec3 rgb2hsv(vec3 c){
        //         vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
        //         vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
        //         vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
        //         float d = q.x - min(q.w, q.y);
        //         float e = 1.0e-10;
        //         return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
        //     }
        //     vec3 hsv2rgb(vec3 c){
        //         vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0), 6.0)-3.0)-1.0, 0.0, 1.0);
        //         rgb = rgb * rgb * (3.0 - 2.0 * rgb);
        //         return c.z * mix(vec3(1.0), rgb, c.y);
        //     }

        //     float random(vec2 st){
        //         return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* 43758.5453123);
        //     }
            
        //     void main(){
        //         vec2 st = vUv * float(rows);
        //         vec2 ipos = floor(st);
        //         float color = random(ipos);
        //         gl_FragColor = vec4(hsv2rgb(vec3(color,1.0,1.0)),1.0);
        //     }
        
        // `
        
        // 真正的随机迷宫图案
        const fragment = `
            #ifdef GL_ES
            precision highp float;
            #endif

            uniform float r;
            uniform float utime;
            uniform int rows;
            varying vec2 vUv;
            
            float random(vec2 st){
                return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* 43758.5453123) * r;
            }
            
            vec2 truchetPattern(vec2 st, float index){
                if(index > 0.75){
                    st = vec2(1.0)-st;
                }else if(index > 0.5){
                    st = vec2(1.0-st.x,st.y);
                }else if(index > 0.1){
                    st = vec2(st.x,1.0-st.y);
                }
                return st;
            }

            void main(){
                vec2 st = vUv * float(rows);
                vec2 fpos = fract(st);//取余
                vec2 ipos = floor(st);//取整

                st = truchetPattern(fpos,random(ipos));

                float color = 0.0;
                color = smoothstep(st.x-0.3,st.x,st.y) - 
                        smoothstep(st.x,st.x+0.3,st.y);

                gl_FragColor = vec4(vec3(color),1.0);
            }
        
        `

        // 第二步：
        const program = renderer.compileSync(fragment,vertex)
        renderer.useProgram(program)

        // 第三步：
        renderer.uniforms.utime = 1
        renderer.uniforms.rows = 20
        renderer.uniforms.r = Math.random()

        // 第四步：
        renderer.setMeshData([
            {
                // 顶点坐标
                positions:[
                    [-1,-1],
                    [-1,1],
                    [1,1],
                    [1,-1],
                ],
                // 设置变量
                attributes:{
                    // 纹理坐标
                    uv:[
                        [0,0],
                        [0,1],
                        [1,1],
                        [1,0],
                    ]
                },
                // 三角剖分
                cells:[[0,1,2],[2,0,3]]
            }
        ])

        // 第五步：
        renderer.render()


    </script>
</body>
</html>